package com.ht.api.util;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import java.util.*;

import com.ht.api.db.exception.HtException;

@Data
public class ParamParser {

    @Data
    public static class ParamInfo {
        private String name;        // 参数名
        private String note;        // 完整说明
        private String simpleNote;  // 简短说明
        private String path;        // 参数路径
        private String type;        // 参数类型
        private boolean required;   // 是否必填
    }

    /**
     * 从说明中提取简短说明
     */
    private String extractSimpleNote(String note) {
        if (note == null || note.isEmpty()) return "";
        int endIndex = note.indexOf("，");
        return endIndex > -1 ? note.substring(0, endIndex) : note;
    }

    /**
     * 根据JSON值判断类型
     */
    private String getTypeFromValue(Object value) {
        if (value instanceof JSONArray) return "Array";
        if (value instanceof JSONObject) return "Object";
        if (value instanceof String) return "String";
        if (value instanceof Number) return "Number";
        if (value instanceof Boolean) return "Boolean";
        return "Object";
    }

    /**
     * 递归查找所有叶子节点路径
     */
    private void findLeafPaths(String currentPath, Object obj, Map<String, Object> paths) {
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            for (String key : json.keySet()) {
                String newPath = currentPath.isEmpty() ? key : currentPath + "." + key;
                Object value = json.get(key);
                if (value instanceof JSONObject) {
                    findLeafPaths(newPath, value, paths);
                } else if (value instanceof JSONArray) {
                    JSONArray array = (JSONArray) value;
                    if (!array.isEmpty()) {
                        if (array.get(0) instanceof JSONObject) {
                            // 处理数组中的对象
                            for (int i = 0; i < array.size(); i++) {
                                findLeafPaths(newPath + "[" + i + "]", array.get(i), paths);
                            }
                        } else {
                            // 处理基本类型数组
                            paths.put(newPath, array);
                        }
                    }
                } else {
                    paths.put(newPath, value);
                }
            }
        }
    }

    /**
     * 主解析方法
     */
    public JSONArray parseParams(String paramText, String jsonExample) {
        // 解析参数说明文本
        Map<String, ParamInfo> paramMap = new LinkedHashMap<>();
        String[] lines = paramText.split("\n");

        // 解析表头
        Map<String, Integer> headerIndexMap = new HashMap<>();
        String[] headers = lines[0].trim().split("\\s+");
        for (int i = 0; i < headers.length; i++) {
            if (headers[i].contains("参数")) headerIndexMap.put("param", i);
            if (headers[i].contains("必填") || headers[i].contains("必须")) headerIndexMap.put("required", i);
            if (headers[i].contains("说明")) headerIndexMap.put("desc", i);
        }

        // 解析参数行，构建参数定义映射
        for (int i = 1; i < lines.length; i++) {
            String line = lines[i].trim();
            if (line.isEmpty()) continue;

            String[] parts = line.split("\\s+");
            if (parts.length < 2) continue;

            ParamInfo param = new ParamInfo();
            int paramIndex = headerIndexMap.getOrDefault("param", 0);
            String paramName = parts[paramIndex];
            param.setName(paramName);

            Integer descIndex = headerIndexMap.get("desc");
            if (descIndex != null && descIndex < parts.length) {
                param.setNote(parts[descIndex]);
                param.setSimpleNote(extractSimpleNote(parts[descIndex]));
            }

            Integer requiredIndex = headerIndexMap.get("required");
            if (requiredIndex != null && requiredIndex < parts.length) {
                param.setRequired("是".equals(parts[requiredIndex]));
            }

            // 存储参数定义，使用参数名的最后一部分作为key
            String[] nameParts = paramName.split("\\.");
            String lastPart = nameParts[nameParts.length - 1];
            paramMap.put(lastPart, param);
            // 同时存储完整路径
            paramMap.put(paramName, param);
        }

        List<ParamInfo> result = new ArrayList<>();

        // 如果有JSON示例，使用它来补充信息
        if (jsonExample != null && !jsonExample.isEmpty()) {
            JSONObject jsonObj = JSONUtil.parseObj(jsonExample);
            Map<String, Object> leafPaths = new LinkedHashMap<>();
            findLeafPaths("", jsonObj, leafPaths);

            // 处理每个叶子节点
            for (Map.Entry<String, Object> entry : leafPaths.entrySet()) {
                String jsonPath = entry.getKey();
                Object value = entry.getValue();

                // 获取基础参数名
                final String baseParamName = jsonPath.contains("[") ?
                        jsonPath.replaceAll("\\[(\\d+)\\]", "[$1]") : jsonPath;

                // 分解路径
                String[] pathParts = baseParamName.split("\\.");

                // 查找匹配的参数定义
                ParamInfo matchedParam = null;

                // 1. 尝试完整路径匹配
                matchedParam = paramMap.get(baseParamName);

                // 2. 尝试最后一部分匹配
                if (matchedParam == null && pathParts.length > 0) {
                    String lastPart = pathParts[pathParts.length - 1];
                    matchedParam = paramMap.get(lastPart);
                }

                // 3. 尝试部分路径匹配
                if (matchedParam == null) {
                    for (String key : paramMap.keySet()) {
                        String[] keyParts = key.split("\\.");
                        if (keyParts.length > 1 && baseParamName.endsWith(key)) {
                            matchedParam = paramMap.get(key);
                            break;
                        }
                    }
                }

                // 如果找到匹配的参数定义，创建新的参数信息
                if (matchedParam != null) {
                    ParamInfo newParam = new ParamInfo();
                    newParam.setName(baseParamName);
                    newParam.setNote(matchedParam.getNote());
                    newParam.setSimpleNote(matchedParam.getSimpleNote());
                    newParam.setRequired(matchedParam.isRequired());
                    newParam.setPath("$." + jsonPath);
                    newParam.setType(getTypeFromValue(value));
                    result.add(newParam);
                }
            }
        } else {
            // 如果没有JSON示例，返回所有参数定义
            result.addAll(paramMap.values());
        }


        return JSONUtil.parseArray(result);
    }

    /**
     * 根据路径在JSON中设置值
     */
    private void setValueByPath(JSONObject root, String path, Object value) {
        String[] parts = path.substring(2).split("\\."); // 去掉开头的 $.
        JSONObject current = root;

        for (int i = 0; i < parts.length - 1; i++) {
            String part = parts[i];

            if (part.contains("[")) {
                String arrayName = part.substring(0, part.indexOf("["));
                int index = Integer.parseInt(part.substring(part.indexOf("[") + 1, part.indexOf("]")));

                if (!current.containsKey(arrayName)) {
                    current.set(arrayName, new JSONArray());
                }
                JSONArray array = current.getJSONArray(arrayName);

                while (array.size() <= index) {
                    array.add(new JSONObject());
                }
                current = array.getJSONObject(index);
            } else {
                if (!current.containsKey(part)) {
                    current.set(part, new JSONObject());
                }
                current = current.getJSONObject(part);
            }
        }

        String lastPart = parts[parts.length - 1];
        if (lastPart.contains("[")) {
            String arrayName = lastPart.substring(0, lastPart.indexOf("["));
            int index = Integer.parseInt(lastPart.substring(lastPart.indexOf("[") + 1, lastPart.indexOf("]")));
            if (!current.containsKey(arrayName)) {
                current.set(arrayName, new JSONArray());
            }
            JSONArray array = current.getJSONArray(arrayName);
            while (array.size() <= index) {
                array.add(null);
            }
            array.set(index, value);
        } else {
            current.set(lastPart, value);
        }
    }

    /**
     * 清理JSON中的空对象
     */
    private void cleanupEmptyObjects(Object obj) {
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            json.keySet().removeIf(key -> {
                Object value = json.get(key);
                if (value instanceof JSONObject) {
                    cleanupEmptyObjects(value);
                    return ((JSONObject) value).isEmpty();
                }
                if (value instanceof JSONArray) {
                    cleanupEmptyObjects(value);
                    return ((JSONArray) value).isEmpty();
                }
                return false;
            });
        } else if (obj instanceof JSONArray) {
            JSONArray array = (JSONArray) obj;
            for (int i = array.size() - 1; i >= 0; i--) {
                Object value = array.get(i);
                if (value instanceof JSONObject) {
                    cleanupEmptyObjects(value);
                    if (((JSONObject) value).isEmpty()) {
                        array.remove(i);
                    }
                } else if (value instanceof JSONArray) {
                    cleanupEmptyObjects(value);
                    if (((JSONArray) value).isEmpty()) {
                        array.remove(i);
                    }
                } else if (value == null) {
                    array.remove(i);
                }
            }
        }
    }

    /**
     * 组装JSON
     */
    public JSONObject assembleJson(JSONArray params, Map<String, Object> values) {
        JSONObject result = new JSONObject();

        // 按路径长度排序，确保先处理上层路径
        List<ParamInfo> sortedParams = fromJsonArray(params);
        sortedParams.sort(Comparator.comparing(p -> p.getPath().split("\\.").length));

        try {
	        for (ParamInfo param : sortedParams) {
	            if (values.containsKey(param.getName())) {
	                Object value = values.get(param.getName());
	                if ("Number".equals(param.getType()) && value != null) {
	                	value = Integer.parseInt(value.toString());
	                }
					setValueByPath(result, param.getPath(), value);
	            }
	        }
        } catch (NumberFormatException e) {
        	throw new HtException("接口参数为Number，但传递的参数不能转为int~");
        }

        // 清理空对象
        cleanupEmptyObjects(result);

        return result;
    }

    // 从JSON字符串转换回List<ParamInfo>
    public static List<ParamInfo> fromJsonArray(JSONArray jsonArray) {

        // 转换为List<ParamInfo>
        List<ParamInfo> params = new ArrayList<>();
        for (Object obj : jsonArray) {
            JSONObject jsonObj = (JSONObject) obj;
            ParamInfo param = new ParamInfo();
            param.setName(jsonObj.getStr("name"));
            param.setNote(jsonObj.getStr("note"));
            param.setSimpleNote(jsonObj.getStr("simpleNote"));
            param.setPath(jsonObj.getStr("path"));
            param.setType(jsonObj.getStr("type"));
            param.setRequired(jsonObj.getBool("required", false));
            params.add(param);
        }

        return params;
    }

}